#include "private_implementations/JsonArray.h"
#include "private_implementations/JsonObject.h"
#include "private_implementations/JsonParser.h"
#include <sstream>
#include <Windows.h>
#include <fstream>

using namespace simframework::json;

std::string to_utf8(const wchar_t* buffer, int len)
{
	int nChars = ::WideCharToMultiByte(
		CP_UTF8,0,buffer,len,NULL,0,NULL,NULL);
	if (nChars == 0) return "";

	std::string newbuffer;
	newbuffer.resize(nChars) ;
	::WideCharToMultiByte(
		CP_UTF8,0,buffer,len,const_cast< char* >(newbuffer.c_str()),
		nChars,NULL,NULL); 

	return newbuffer;
}

std::string to_utf8(const std::wstring& str)
{
	return to_utf8(str.c_str(), (int)str.size());
}

int main()
{
 	std::wstring str;
// 	{		
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Object jObj(jsonStream);			
// 		}
// 		
// 	}
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Array jArr(jsonStream);
// 		}
// 		
// 	}
// 
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Object jObj(jsonStream);
// 			jObj.insert("key1", "value");
// 			jObj.insert("key2", 5);
// 			jObj.insert("key3", false);
// 			jObj.insert("key2", true);
// 			jObj.insert("key3", simframework::json::null);
// 		}
// 		
// 	}
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Array jArr(jsonStream);
// 			jArr.push_back("value");
// 			jArr.push_back(5);
// 			jArr.push_back(false);
// 			jArr.push_back(true);
// 			jArr.push_back(simframework::json::null);
// 		}
// 		
// 	}
// 
// 	{
// 		std::wstringstream jsonStream;
// 		{		
// 			simframework::json::Object jObj(jsonStream);
// 			{
// 				simframework::json::Object jObjTmp = jObj.startObject("key");
// 				jObjTmp.insert("key2", 5);
// 			}
// 		}
// 		
// 	}
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Array jArr(jsonStream);
// 			{
// 				simframework::json::Array jArrTmp = jArr.startArray();
// 				jArrTmp.push_back("value");
// 				jArrTmp.push_back(5);
// 			}
// 		}
// 		
// 	}
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Array jArr(jsonStream);
// 			{
// 				{
// 					simframework::json::Object jObj1 = jArr.startObject();
// 					simframework::json::Object jObj2 = jObj1.startObject("A");
// 					jObj2.insert("id", 28);
// 					jObj2.insert("Title", "Sweden");
// 				}				
// 
// 				{
// 					simframework::json::Object jObj3 = jArr.startObject();
// 					simframework::json::Object jObj4 = jObj3.startObject("A");
// 					jObj4.insert("id", 56);
// 					jObj4.insert("Title", "USA");
// 				}
// 
// 				{
// 					simframework::json::Object jObj5 = jArr.startObject();
// 					simframework::json::Object jObj6 = jObj5.startObject("A");
// 					jObj6.insert("id", 89);
// 					jObj6.insert("Title", "England");
// 				}
// 			}
// 		}
// 		
// 	}
// 	{
// 		std::wstringstream jsonStream;
// 		{
// 			simframework::json::Object jObj(jsonStream);
// 			{
// 				int* pi = NULL;
// 				simframework::json::Array arr = jObj.startArray("customers");
// 				{
// 					simframework::json::Object obj1 = arr.startObject();					
// 					{
// 						simframework::json::Object obj2 = obj1.startObject("customer");
// 						{
// 							obj2.insert("id", 1);
// 							obj2.insert("customerID", "custA");
// 							obj2.insert("customerAddress", "Alpha Way");
// 							obj2.insert("isAlive", false);
// 							obj2.insert("aaa",simframework::json::null);
// 						}
// 					}
// 				}
// 				{
// 					simframework::json::Object obj1 = arr.startObject();					
// 					{
// 						simframework::json::Object obj2 = obj1.startObject("customer");
// 						{
// 							obj2.insert("id", 2);
// 							obj2.insert("customerID", "custA");
// 							obj2.insert("customerAddress", "Alpha Way");
// 							obj2.insert("isAlive", true);
// 							obj2.insert("aaa",simframework::json::null);
// 						}
// 					}
// 				}
// 				{
// 					simframework::json::Object obj1 = arr.startObject();					
// 					{
// 						simframework::json::Object obj2 = obj1.startObject("customer");
// 						{
// 							obj2.insert("id", 3);
// 							obj2.insert("customerID", "custA");
// 							obj2.insert("customerAddress", "Alpha Way");
// 							obj2.insert("isAlive", false);
// 							obj2.insert("aaa",simframework::json::null);
// 						}
// 					}
// 				}
// 			}
// 		}
// 		//{
// 		//	"customers":[
// 		//	{
// 		//		"customer":{
// 		//			"id":1,
// 		//				"customerID":true,
// 		//				"customerAddress":true,
// 		//				"isAlive":false,
// 		//				"aaa":null
// 		//		}
// 		//	},
// 		//	{
// 		//		"customer":{
// 		//			"id":2,
// 		//				"customerID":true,
// 		//				"customerAddress":true,
// 		//				"isAlive":true,
// 		//				"aaa":null
// 		//		}
// 		//	},
// 		//	{
// 		//		"customer":{
// 		//			"id":3,
// 		//				"customerID":true,
// 		//				"customerAddress":true,
// 		//				"isAlive":false,
// 		//				"aaa":null
// 		//		}
// 		//	}
// 		//	]
// 		//}
// 		str = jsonStream.str();
// 	}
// 
 	std::wstringstream ss;
 	{
 		simframework::json::Object jObj(ss);
		std::wstring sss = L"a \" \\ / \b \f \n \r \t \uffff";
 		//jObj.insert(L"jsonID", L"123");
		jObj.insert(L"a", L"a \" \\ / \b \f \n \r \t \uffff");
 		jObj.insert(L"operation", L"createCrowd");
 		jObj.insert(L"isChaotic", true);
 		{
 			simframework::json::Object jObj2 = jObj.startObject(L"parameters");
 			{
 				jObj2.insert(L"noOfUnits", 10);
 				{
 					simframework::json::Array arr = jObj2.startArray(L"unitTypes");
 					{
 						arr.push_back(L"VBS2_AU_Army_Rifleman_W_F88A1");
 						arr.push_back(L"vbs2_af_taliban_ak74pso");
 						arr.push_back(L"vbs2_af_civ_man_1");
 						arr.push_back(L"vbs2_af_civ_man_2");
 					}
 				}
 				jObj2.insert(L"mapName",L"porto");
 				{
 					simframework::json::Object jObj3 = jObj2.startObject(L"area");
 					{
 						jObj3.insert(L"type", L"circle");
 						{
 							simframework::json::Object jObj4 = jObj3.startObject(L"position");
 							{
 								jObj4.insert(L"x",2935.18);
 								jObj4.insert(L"y",2218.34);
 								jObj4.insert(L"z",5.0357);
 							}
 						}
 						jObj3.insert(L"radius", 100);
 					}
 				}
 			}
 		}		
 	}
 	str = ss.str();

	std::ofstream f;
	f.open("Regression.txt", std::ios::out | std::ios::binary);
	f << to_utf8(str);
	f.close();
	
/*
	JsonToken tk(str);	

	if (tk.tokenType == JsonTokenType::JSON_OBJECT)
	{
		JsonToken tk2 = tk.next();

	}*/

//	std::wstring jsonStr = "{"
//	"\"aaaa\":"
//	"{"
//		"\"id\":1,"
//		"\"abc\":true,"
//		"\"fds\":true,"
//		"\"vvx\":false,"
//		"\"ddd\":null"
//	"},"
//	
//	"\"customers\":"
//	"["
//		"{"
//			"\"customer\":"
//			"{"
//				"\"id\":1,"
//				"\"customerID\":true,"
//				"\"customerAddress\":true,"
//				"\"isAlive\":false,"
//				"\"aaa\":null"
//			"}"
//		"},"
//		"{"
//			"\"customer\":"
//			"{"
//				"\"id\":2,"
//				"\"customerID\":true,"
//				"\"customerAddress\":true,"
//				"\"isAlive\":true,"
//				"\"aaa\":null"
//			"}"
//		"},"
//		"{"
//			"\"customer\":"
//			"{"
//				"\"id\":3,"
//				"\"customerID\":true,"
//				"\"customerAddress\":true,"
//				"\"isAlive\":false,"
//				"\"aaa\":null"
//			"}"
//		"}"
//	"]"
//"}";
//
//	
//JsonParser parser(jsonStr);
//	const IJsonNode* node = parser.parse();
//
//	const JsonNode<JsonObjectNode>* objNode = node->getJsonNode<JsonObjectNode>();	
//	const JsonObjectNode* jon1 = objNode->getValue<const JsonObjectNode*>("aaaa");
//	
//	double d = jon1->getValue<double>("id");
//	bool b1 = jon1->getValue<bool>("fds");
//	bool b12 = jon1->getValue<bool>("vvx");
//	//std::wstring b14 = jon1->getValue<std::wstring>("vvx");
//
//	const JsonArrayNode* jan = objNode->getValue<const JsonArrayNode*>(std::wstring("customers"));
//	const JsonObjectNode* jon2 = jan->getValue<const JsonObjectNode*>(0);
//	const JsonObjectNode* jon3 = jon2->getValue<const JsonObjectNode*>("customer");

	return 0;
}